﻿using JNPF.Basics.Models;
using JNPF.Basics.Models.Permission.Dtos.AuthorizeData;
using JNPF.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace JNPF.Basics.Logic
{
    /// <summary>
    /// 操作权限
    /// 版 本：V3.0.0
    /// 版 权：引迈信息技术有限公司（https://www.jnpfsoft.com）
    /// 作 者：JNPF开发平台组
    /// 日 期：2017.11.07 
    /// </summary>
    public class AuthorizeBll
    {
        private AuthorizeIService service = new AuthorizeService();

        /// <summary>
        /// 获取权限（菜单、按钮、列表）
        /// </summary>
        /// <param name="isCache">默认缓存开启</param>
        /// <returns></returns>
        public async Task<AuthorizeModel> GetAuthorize(bool isCache = true)
        {
            try
            {
                var userInfo = UserProvider.Instance.Get();
                var authorizeModel = new AuthorizeModel();
                authorizeModel = await service.GetAuthorize(userInfo.IsAdministrator, userInfo.UserId);
                return authorizeModel;
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }

        /// <summary>
        /// 根据用户Id获取列表
        /// </summary>
        /// <param name="isAdmin">是否管理员</param>
        /// <param name="userId">用户主键</param>
        /// <returns></returns>
        public async Task<List<AuthorizeEntity>> GetListByUserId(bool isAdmin, string userId)
        {
            try
            {
                return await service.GetListByUserId(isAdmin, userId);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 根据对象Id获取列表
        /// </summary>
        /// <param name="objectId">对象主键</param>
        /// <returns></returns>
        public async Task<List<AuthorizeEntity>> GetListByObjectId(string objectId)
        {
            try
            {
                return await service.GetListByObjectId(objectId);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 保存权限
        /// </summary>
        /// <param name="objectId">对象主键</param>
        /// <param name="authorizeList">权限数据</param>
        public async Task Save(string objectId, List<AuthorizeEntity> authorizeList)
        {
            try
            {
                var creatorTime = DateTime.Now;
                var creatorUserId = UserProvider.Instance.Get().UserId;
                foreach (AuthorizeEntity entity in authorizeList)
                {
                    entity.Id = CommonHelper.Guid;
                    entity.SortCode = authorizeList.IndexOf(entity);
                    entity.CreatorTime = creatorTime;
                    entity.CreatorUserId = creatorUserId;
                    entity.ObjectId = objectId;
                }
                await service.Create(objectId, authorizeList);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 保存批量权限
        /// </summary>
        /// <param name="objectList">对象数据</param>
        /// <param name="entitys">权限数据</param>
        public async Task SaveBatch(List<AuthorizeEntity> objectList, List<AuthorizeEntity> authorizeList)
        {
            try
            {
                var creatorTime = DateTime.Now;
                var creatorUserId = UserProvider.Instance.Get().UserId;
                var entityList = new List<AuthorizeEntity>();
                foreach (var objectItem in objectList)
                {
                    foreach (AuthorizeEntity entityItem in authorizeList)
                    {
                        var entity = new AuthorizeEntity();
                        entity.Id = CommonHelper.Guid;
                        entity.ItemId = entityItem.ItemId;
                        entity.ItemType = entityItem.ItemType;
                        entity.ObjectId = objectItem.ObjectId;
                        entity.ObjectType = objectItem.ObjectType;
                        entity.SortCode = authorizeList.IndexOf(entityItem);
                        entity.CreatorTime = creatorTime;
                        entity.CreatorUserId = creatorUserId;
                        entityList.Add(entity);
                    }
                }
                await service.Create(entityList);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }

        /// <summary>
        /// 设置/更新功能权限
        /// </summary>
        /// <param name="itemId"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task UpdateModel(string itemId, AuthorizeModelInput input)
        {
            var authorizeList = new List<AuthorizeEntity>();
            var creatorUserId = UserProvider.Instance.Get().UserId;
            foreach (var item in input.objectId)
            {
                var entity = new AuthorizeEntity();
                entity.Id = CommonHelper.Guid;
                entity.CreatorTime = DateTime.Now;
                entity.CreatorUserId = creatorUserId;
                entity.ItemId = itemId;
                entity.ItemType = input.itemType;
                entity.ObjectId = item;
                entity.ObjectType = input.objectType;
                entity.SortCode = CommonHelper.SortCode;
                authorizeList.Add(entity);
            }
            await service.CreatePortal(itemId, authorizeList);
        }
        /// <summary>
        /// 获取功能权限数据
        /// </summary>
        /// <param name="itemId"></param>
        /// <param name="ObjectType"></param>
        /// <returns></returns>
        public async Task<List<AuthorizeEntity>> GetAuthorizeModelList(string itemId, string ObjectType)
        {
            try
            {
                return await service.GetAuthorizeModelList(itemId, ObjectType);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }

        /// <summary>
        /// 获取条件过滤
        /// </summary>
        /// <param name="userInfo">用户信息</param>
        /// <param name="moduleId">功能Id</param>
        /// <returns></returns>
        public Expression<Func<T, bool>> GetCondition<T>(UserInfo userInfo, string moduleId) where T : new()
        {
            try
            {
                var queryWhere = ExtLinq.True<T>();
                var resourceList = this.GetAuthorize().Result.ResourceList.FindAll(q => q.ModuleId == moduleId);
                foreach (var item in resourceList)
                {
                    var itemWhere = ExtLinq.True<T>();
                    var conditionModelList = JsonHelper.ToList<AuthorizeModuleResourceConditionModel>(item.ConditionJson);
                    foreach (var conditionItem in conditionModelList)
                    {
                        var subWhere = new ExtLinq<T>();
                        foreach (var fieldItem in conditionItem.groups)
                        {
                            var itemField = fieldItem.field.Replace("F_", "");
                            var itemValue = (object)fieldItem.value;
                            var itemMethod = (SearchMethod)Enum.Parse(typeof(SearchMethod), fieldItem.op);
                            if (itemValue.ToString() == "@userId") //当前用户Id
                            {
                                subWhere.CreateExpression(itemField, userInfo.UserId, itemMethod);
                            }
                            else if (itemValue.ToString() == "@organizeId")  //当前部门Id
                            {
                                subWhere.CreateExpression(itemField, userInfo.OrganizeId, itemMethod);
                            }
                            else if (itemValue.ToString() == "@subordinateId")//我的下属
                            {
                                if (userInfo.SubordinateIds.Length > 0)
                                {
                                    subWhere.CreateExpression(itemField, userInfo.SubordinateIds.ToList<object>());
                                }
                            }
                            else//任意文本
                            {
                                if (fieldItem.type == "Int32")
                                    subWhere.CreateExpression(itemField, itemValue.ToInt(), itemMethod);
                                else if (fieldItem.type == "Double")
                                    subWhere.CreateExpression(itemField, itemValue.ToDecimal(), itemMethod);
                                else
                                    subWhere.CreateExpression(itemField, itemValue.ToString(), itemMethod);
                            }
                        }
                        if (conditionItem.logic == "and")
                        {
                            itemWhere = itemWhere.And(subWhere.GetLambda());
                        }
                        else
                        {
                            if (subWhere.GetLambda() != null)
                            {
                                itemWhere = itemWhere.Or(subWhere.GetLambda());
                            }
                        }
                    }
                    queryWhere = resourceList.IndexOf(item) == 0 ? queryWhere.And(itemWhere) : queryWhere.Or(itemWhere);
                }
                return queryWhere;
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 获取条件过滤
        /// </summary>
        /// <param name="userInfo">用户信息</param>
        /// <param name="moduleId">功能模块Id</param>
        /// <returns></returns>
        public string GetCondition(UserInfo userInfo, string moduleId)
        {
            try
            {
                var queryWhere = new StringBuilder();
                var resourceList = this.GetAuthorize().Result.ResourceList.FindAll(q => q.ModuleId == moduleId);
                foreach (var item in resourceList)
                {
                    var itemWhere = new StringBuilder();
                    var conditionModelList = JsonHelper.ToList<AuthorizeModuleResourceConditionModel>(item.ConditionJson);
                    foreach (var conditionItem in conditionModelList)
                    {
                        var subWhere = new StringBuilder();
                        foreach (var fieldItem in conditionItem.groups)
                        {
                            if (conditionItem.groups.IndexOf(fieldItem) > 0)
                            {
                                subWhere.Append(" AND ");
                            }
                            var itemField = fieldItem.field.Replace("F_", "");
                            var itemValue = (object)fieldItem.value;
                            var itemMethod = (SearchMethod)Enum.Parse(typeof(SearchMethod), fieldItem.op);
                            if (itemValue.ToString() == "@userId") //当前用户Id
                            {
                                subWhere.Append(string.Format("{0} = '{1}'", itemField, userInfo.UserId));
                            }
                            else if (itemValue.ToString() == "@organizeId")  //当前部门Id
                            {
                                subWhere.Append(string.Format("{0} = '{1}'", itemField, userInfo.OrganizeId));
                            }
                            else if (itemValue.ToString() == "@subordinateId")//我的下属
                            {
                                if (userInfo.SubordinateIds.Length > 0)
                                {
                                    subWhere.Append(string.Format("{0} IN ('{1}')", itemField, string.Join("','", userInfo.SubordinateIds)));
                                }
                            }
                            else//任意文本
                            {
                                if (fieldItem.type == "Int32")
                                    itemValue = itemValue.ToInt();
                                else if (fieldItem.type == "Double")
                                    itemValue = itemValue.ToDecimal();
                                else
                                    itemValue = itemValue.ToString();
                                switch (itemMethod)
                                {
                                    case SearchMethod.Equal:
                                        subWhere.Append(string.Format("{0} = '{1}'", itemField, itemValue.ToString()));
                                        break;
                                    case SearchMethod.NotEqual:
                                        subWhere.Append(string.Format("{0} <> '{1}'", itemField, itemValue.ToString()));
                                        break;
                                    case SearchMethod.LessThan:
                                        subWhere.Append(string.Format("{0} < '{1}'", itemField, itemValue));
                                        break;
                                    case SearchMethod.LessThanOrEqual:
                                        subWhere.Append(string.Format("{0} <= '{1}'", itemField, itemValue));
                                        break;
                                    case SearchMethod.GreaterThan:
                                        subWhere.Append(string.Format("{0} > '{1}'", itemField, itemValue));
                                        break;
                                    case SearchMethod.GreaterThanOrEqual:
                                        subWhere.Append(string.Format("{0} >= '{1}'", itemField, itemValue));
                                        break;
                                }
                            }
                        }
                        if (conditionModelList.IndexOf(conditionItem) > 0 && subWhere.Length != 0)
                        {
                            queryWhere.Append(" " + conditionItem.logic + " ");
                        }
                        itemWhere.Append(subWhere);
                    }
                    if (queryWhere.Length == 0)
                        queryWhere.Append(" AND (" + itemWhere + ")");
                    else
                        queryWhere.Append(" OR (" + itemWhere + ")");
                }
                return queryWhere.ToString();
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }


    }
}
